package com.ebring.shareEducation.controller;
import com.ebring.shareEducation.bean.CoinOrder;
import com.ebring.shareEducation.bean.PayOrder;
import com.ebring.shareEducation.dao.PayOrderMapper;
import com.ebring.shareEducation.dao.UserMapper;
/*
import com.ebring.shareEducation.service.CoinOrderService;
*/
import com.ebring.shareEducation.service.PayOrderService;
import com.ebring.shareEducation.utils.RspMsg;
import com.ebring.shareEducation.utils.UuidUtils;
import com.ebring.shareEducation.utils.WeChat.*;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 金币充值
 */
@Controller
@PropertySource({"classpath:wechatPay.properties"})
public class WeChatGodcoinPayController {
    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(WeChatPayController.class);

    @Value("${baseUrl}")
    private String baseUrl;
    @Value("${APP_ID}")
    private String appid;
    @Value("${appsecret}")
    private String appsecret;
    @Value("${partnerkey}")
    private String partnerkey;
    @Value("${mch_id}")
    private String mch_id;
    @Value("${ip}")
    private String ip;
    @Value("${GodcoinNotify_url}")
    private String notify_url;

    @Autowired
    private PayOrderService payOrderService;
    @Autowired
    private PayOrderMapper payOrderMapper;
    @Autowired
    private UserMapper userMapper;
  /*  @Autowired
    private CoinOrderService coinOrderService;*/

    private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 微信网页授权获取用户基本信息，先获取 code，跳转 url 通过 code 获取 openId 跳转支付页面调微信公众号支付
     *
     * @return
     */
    @RequestMapping("/WeChatGodcoinPay/userAuth")
    @ResponseBody
    public RspMsg<String> userAuth(HttpServletRequest request, HttpServletResponse response) {
        RspMsg rspMsg = new RspMsg();
        String money = request.getParameter("money");
        String userId = request.getParameter("userId");
        money = TranspositionCoin.changeY2F(money);//元转分
        String orderId = "SECM" + IdsUtil.genOrderNo();//生成订单流水

        String date = formatter.format(new Date());//格式化数据
        PayOrder payOrder = new PayOrder();
        payOrder.setNo(orderId);
        payOrder.setOpenid(userId);//用户id
        payOrder.setTimeStart(date);//交易时间
        payOrder.setPayType("030");//010 会员充值 020任务支付  030金币充值
        payOrder.setTotalFee(money);//支付金额
        payOrder.setTradeState("0");//0 未支付 1 支付成功 2 转入退款 3 已关闭 4 已撤销 5 用户支付中 6 支付失败
        payOrderService.insertPayOrder(payOrder);
        try {
            String totalFee = money;
            //授权后要跳转的链接
            String backUri = baseUrl +"/WeChatGodcoinPay/toPay";
            backUri = backUri + "?orderId=" + orderId + "&totalFee=" + totalFee;
            //URLEncoder.encode 后可以在backUri 的url里面获取传递的所有参数
            backUri = URLEncoder.encode(backUri);
            //scope 参数视各自需求而定，这里用scope=snsapi_base 不弹出授权页面直接授权目的只获取统一支付接口的openid
            String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
                    "appid=" + appid +
                    "&redirect_uri=" +
                    backUri +
                    "&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect";
            LOGGER.info("in userAuth,sendRedirectUrl::" + url);
            rspMsg.setOK();
            rspMsg.setResult(url);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rspMsg;
    }

    /**
     * 支付
     *
     * @param request
     * @param response
     * @param model
     * @return
     * @throws Exception
     */
    @GetMapping("/WeChatGodcoinPay/toPay")
    public String toPay(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
        //获取统一下单需要的openid
        String code = request.getParameter("code");
        String openId = "";
        String URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
                + appid + "&secret=" + appsecret + "&code=" + code + "&grant_type=authorization_code";
        LOGGER.info("in BankPayController,httpsRequestURL:" + URL);
        //获取openId
        net.sf.json.JSONObject jsonObject = CommonUtil.httpsRequest(URL, "GET", null);
        if (null != jsonObject) {
            try {
                openId = jsonObject.getString("openid");
                LOGGER.info("in BankPayController,openId:" + openId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        String orderId = request.getParameter("orderId");
        String totalFee = request.getParameter("totalFee");
        //随机数
        String nonce_str = UUID.randomUUID().toString().replaceAll("-", "");
        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", appid);//appid
        packageParams.put("mch_id", mch_id);//商户id
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("body", "fee");
        packageParams.put("out_trade_no", orderId);
        packageParams.put("total_fee", totalFee);
        packageParams.put("spbill_create_ip", ip);
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", "JSAPI");
        packageParams.put("openid", openId);

        RequestHandler reqHandler = new RequestHandler(request, response);
        reqHandler.init(appid, appsecret, partnerkey);

        String sign = reqHandler.createSign(packageParams);
        LOGGER.info("in toWeChatOfficialAccountPay,sign:" + sign);
        String xml = "<xml>" +
                "<appid>" + appid + "</appid>" +
                "<mch_id>" + mch_id + "</mch_id>" +
                "<nonce_str>" + nonce_str + "</nonce_str>" +
                "<sign>" + sign + "</sign>" +
                "<body><![CDATA[" + "fee" + "]]></body>" +
                "<out_trade_no>" + orderId + "</out_trade_no>" +
                "<total_fee>" + totalFee + "" + "</total_fee>" +
                "<spbill_create_ip>" + ip + "</spbill_create_ip>" +
                "<notify_url>" + notify_url + "</notify_url>" +
                "<trade_type>" + "JSAPI" + "</trade_type>" +
                "<openid>" + openId + "</openid>" +
                "</xml>";
        LOGGER.info("in toWeChatOfficialAccountPay,xml：" + xml);

        String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        String prepay_id = "";
        try {
            prepay_id = WeixinPayUtil.getOfficialAccountPayNo(createOrderURL, xml);
            LOGGER.info("in BankPayController,prepay_id:" + prepay_id);
            if (prepay_id.equals("")) {
                LOGGER.info("in BankPayController,统一支付接口获取预支付订单出错");
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        SortedMap<String, String> finalpackage = new TreeMap<String, String>();
        String timestamp = Sha1Util.getTimeStamp();
        String packages = "prepay_id=" + prepay_id;//预支付id
        finalpackage.put("appId", appid);
        finalpackage.put("timeStamp", timestamp);
        finalpackage.put("nonceStr", nonce_str);
        finalpackage.put("package", packages);
        finalpackage.put("signType", "MD5");
        String finalsign = reqHandler.createSign(finalpackage);
        model.addAttribute("appId", appid);
        model.addAttribute("timeStamp", timestamp);
        model.addAttribute("nonceStr", nonce_str);
        model.addAttribute("packageValue", packages);
        model.addAttribute("sign", finalsign);
        model.addAttribute("payPrice", totalFee);
        model.addAttribute("tId", orderId);
        return "jsapi";
    }


    @RequestMapping(value = "/WeChatGodcoinPay/notifyUrl")
    @ResponseBody
    public String asyncpayBack(HttpServletRequest request, HttpServletResponse response, Model model) {
        LOGGER.info("in BankPayController,asyncpayBack");
        String xml_review_result = WeixinPayUtil.getXmlRequest(request);
        LOGGER.info("in weixinReceive,微信支付结果:" + xml_review_result);
        String resXml = "";
        Map resultMap = null;
        try {
            resultMap = WeixinPayUtil.doXMLParse(xml_review_result);
            LOGGER.info("in weixinReceive,resultMap:" + resultMap);
            if (resultMap != null && resultMap.size() > 0) {
                String sign_receive = (String) resultMap.get("sign");
                LOGGER.info("in weixinReceive,sign_receive:" + sign_receive);
                resultMap.remove("sign");
                String mch_id = (String) resultMap.get("mch_id");

                String checkSign = WeixinPayUtil.getSign(resultMap, partnerkey);
                LOGGER.info("in weixinReceive,checkSign:" + checkSign);

                //签名校验成功
                if (checkSign != null && sign_receive != null &&
                        checkSign.equals(sign_receive.trim())) {
                    LOGGER.info("in weixinReceive,weixin receive check Sign sucess");
                    try {
                        //获得返回结果
                        String return_code = (String) resultMap.get("return_code");
                        String return_msg = (String) resultMap.get("return_msg");

                        if ("SUCCESS".equals(return_code)) {
                            String out_trade_no = (String) resultMap.get("out_trade_no");
                            String appid = (String) resultMap.get("appid");
                            String transaction_id = (String) resultMap.get("transaction_id");
                            String result_code = (String) resultMap.get("result_code");
                            LOGGER.info("in weixinReceive,weixin pay sucess,out_trade_no:" + out_trade_no);
                            PayOrder payOrder = new PayOrder();
                            if ("SUCCESS".equals(result_code)) {
                                //处理支付成功以后的逻辑，这里是写入相关信息到文本文件里面，如果有订单的处理订单
                                payOrder.setTradeState("1");//0 未支付 1 支付成功 2 转入退款 3 已关闭 4 已撤销 5 用户支付中 6 支付失败
                                Example example = new Example(PayOrder.class);
                                example.or().andEqualTo("no",out_trade_no);
                                PayOrder payOrders = payOrderMapper.selectByExample(example).get(0);
                                CoinOrder coinOrder = new CoinOrder();
                                coinOrder.setCoinId(UuidUtils.getNumberId(22));
                                coinOrder.setCoinId(formatter.format(new Date()));
                                coinOrder.setUserId(payOrders.getOpenid());
                                coinOrder.setGetType("1");
                                coinOrder.setPlusOrMinus("1");
                                coinOrder.setAmount(TranspositionCoin.changeF2Y(payOrders.getTotalFee()));
                                coinOrder.setTaskReleaseId(payOrders.getNo());
/*
                                coinOrderService.addMoney(coinOrder);
*/
                            }else{
                                payOrder.setTradeState("6");
                            }
                            payOrder.setOrderNo(transaction_id);
                            Example example = new Example(PayOrder.class);
                            example.or().andEqualTo("no",out_trade_no);
                            int ss=  payOrderMapper.updateByExampleSelective(payOrder,example);
                            System.out.println(ss);

                            resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                                    + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                        } else {
                            model.addAttribute("payResult", "0");
                            model.addAttribute("err_code_des", "通信错误");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    //签名校验失败
                    LOGGER.error("in weixinReceive,weixin receive check Sign fail");
                }
            }
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resXml;
    }
}
